package com.allwees.support.payment.oceanpay.client;

import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.allwees.bs.core.modelbase.constant.ResultEnum;
import com.allwees.bs.core.modelbase.exception.BusinessException;
import com.allwees.core.common.util.StringUtil;
import com.allwees.support.payment.oceanpay.dto.LogisticsUploadRequest;
import com.allwees.support.payment.oceanpay.dto.LogisticsUploadResult;
import com.allwees.support.payment.oceanpay.dto.RefundApplyRequest;
import com.allwees.support.payment.oceanpay.dto.RefundApplyResult;
import lombok.extern.slf4j.Slf4j;
import retrofit2.Response;

import java.util.Map;

/**
 * @author Daniel
 * @version 1.0.0
 * @since 2020/12/5 20:55
 */
@Slf4j
public class OceanpayRequestClient {

    private static final OceanpayApi API = RetrofitManager.getInstance().getRetrofit().create(OceanpayApi.class);
    /**
     * 退款功能需要登记服务器 IP
     * https://query.oceanpayment.com/service/applyRefund
     * 退款结果推送默认关闭，如需开启请联系 Oceanpayment技术支持人员
     * 退款结果推送依赖于 noticeUrl，如果该笔交易没有 noticeUrl则不进行推送。
     *
     * @param request
     */
    public static void sendRefundApplyRequest(RefundApplyRequest request, String secureCode) {
        try {
            Map<String, Object> params = genRequestParams(request, secureCode);
            Response<RefundApplyResult> response = API.applyRefund(params).execute();
            RefundApplyResult result = response.body();
            boolean success = "00".equals(result.getRefund_results());
            if (!success) {
                log.error("===>sendRefundApplyRequest failed.result:{}",result);
                throw BusinessException.getInstance(ResultEnum.ORDER_CANNOT_REQUEST_REFUND);
            }
        } catch (Exception e) {
            log.error("sendRefundApplyRequest error:{}",e.getMessage(),e);
            throw BusinessException.getInstance(ResultEnum.ORDER_CANNOT_REQUEST_REFUND);
        }
    }

    /**
     * account+terminal+payment_id+refund_type+refund_amount+refund_description+secureCode
     * @param request
     */
    private static Map<String, Object> genRequestParams(RefundApplyRequest request, String secureCode) {
        String signStr =
                StringUtil.join(
                        request.getAccount(),
                        request.getTerminal(),
                        request.getPayment_id(),
                        request.getRefund_type(),
                        request.getRefund_amount(),
                        request.getRefund_description(),
                        secureCode
                );
        request.setSignValue(SecureUtil.sha256(signStr));
        return JSON.parseObject(JSON.toJSONString(request));
    }

    /**
     * 上传物流信息
     * https://query.oceanpayment.com/service/uploadTrackingNo
     */
    public static void sendUploadLogistRequest(LogisticsUploadRequest request, String secureCode) {
        try {
            Map<String, Object> params = genRequestParams(request, secureCode);
            Response<LogisticsUploadResult> response = API.uploadTrackingNo(params).execute();
            LogisticsUploadResult result = response.body();
            boolean sucess = "01".equals(result.getTracking_results());
            if (!sucess) {
                log.error("===>sendUploadLogistRequest failed.result:{}",result);
            }
        } catch (Exception e) {
            log.error("sendUploadLogistRequest error:{}",e.getMessage(),e);
        }
    }

    /**
     * account+terminal+payment_id+order_number+tracking_number+tracking_site+tracking_handler+secureCode
     * @param request
     */
    private static Map<String, Object> genRequestParams(LogisticsUploadRequest request, String secureCode) {
        String signStr =
                StringUtil.join(
                        request.getAccount(),
                        request.getTerminal(),
                        request.getPayment_id(),
                        request.getOrder_number(),
                        request.getTracking_number(),
                        request.getTracking_site(),
                        request.getTracking_handler(),
                        secureCode
                );
        request.setSignValue(SecureUtil.sha256(signStr));
        return JSON.parseObject(JSON.toJSONString(request));
    }
}
